package org.fei.ClassDiagram.WindowComponents;

import org.fei.ClassDiagram.WindowComponents.Diagram;
import org.fei.ClassDiagram.WindowComponents.Message;
import org.fei.ClassDiagram.WindowComponents.MessageJPanel;
import org.fei.ClassDiagram.WindowComponents.PackageDiagram;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import org.fei.ClassDiagram.drawing.Lines.Line;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.fei.ClassDiagram.data.*;
import org.fei.ClassDiagram.drawing.Lines.AsotiationArrow;
import org.fei.ClassDiagram.drawing.Classes.Drawing;
import org.netbeans.api.project.Project;
import org.openide.util.Exceptions;
import org.openide.windows.TopComponent;


@TopComponent.Description(preferredID = "ClassDiagramView", 
persistenceType = TopComponent.PERSISTENCE_NEVER)
@TopComponent.Registration(mode = "explorer", openAtStartup = false)
/**
 *
 * @author Tomas
 */
public class ClassDiagramView extends TopComponent {
    private ArrayList<Data> dataList;
    private JTextArea text;
    
    private Diagram classDiagram;
    private PackageDiagram packageDiagram;
    private ArrayList<Drawing> drawing;
    private JTextField txtFontSize;
    private JButton btnFontSizeLeft;
    private JButton btnFontSizeRight;
    private JCheckBox showAtributes;
    private JCheckBox showAsociations;
    private JCheckBox showAsociationNames;
    private JCheckBox showConstructors;
    private JButton btnExport;
    private JButton btnExport2;
    private JPanel ClassDiagramPanel;
    private JPanel PackageDiagramPanel;
    
    // koli filechooserovi
    private final ClassDiagramView parentClass = this;
    
    // pre zatvorenie posledneho okna
    public static ClassDiagramView lastOpened = null; 
    
    public ClassDiagramView(JPanel panel, String projectName) {
        this.setLayout(new BorderLayout());
        ClassDiagramPanel = new JPanel();
        ClassDiagramPanel.setLayout(new BorderLayout());
        
        if (panel instanceof Diagram) { // ked sa zobrazuje diagram
            this.classDiagram = (Diagram)panel;
            this.initComponents();
            this.add(ClassDiagramPanel, BorderLayout.CENTER);
        }
        else {  // ked sa zobrazuje sprava pre uzivatela
            MessageJPanel message = (MessageJPanel)panel;
            this.add(message, BorderLayout.CENTER);
        }

        this.setName(projectName + " UML diagram");
        this.setVisible(true);        
        Image img = Toolkit.getDefaultToolkit().getImage("org/fei/ClassDiagram/ball.png");
        this.setIcon(img);
        this.toFront();
        this.open();
        this.requestActive();
        ClassDiagramView.lastOpened = this;        
    }

    // panel1 - class diagram, panel2 - packgage diagram
    public ClassDiagramView(JPanel panel1, JPanel panel2, String projectName) {
        this.setLayout(new BorderLayout());
        ClassDiagramPanel = new JPanel();
        ClassDiagramPanel.setLayout(new BorderLayout());

        JTabbedPane tabbedPane = new JTabbedPane();
        
        this.classDiagram = (Diagram)panel1;
        this.initComponents();
        tabbedPane.addTab("Class diagram", ClassDiagramPanel);
        
        PackageDiagramPanel = new JPanel();
        PackageDiagramPanel.setLayout(new BorderLayout());
        this.packageDiagram = (PackageDiagram)panel2;
        initComponentsPackage();
        tabbedPane.addTab("Package diagram", PackageDiagramPanel);
        
        add(tabbedPane, BorderLayout.CENTER);
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
        this.setName(projectName + " UML diagram");
        this.setVisible(true);        
        Image img = Toolkit.getDefaultToolkit().getImage("C:\\Users\\Tomas\\Desktop\\ball.png");
        this.setIcon(img);
        this.toFront();
        this.open();
        this.requestActive();
        ClassDiagramView.lastOpened = this;        
    }
    
    // komponenty class diagramu
    private void initComponents() {
        // rezia pre horny panel
        JPanel frontPanel = new JPanel(new BorderLayout());
        JPanel fontSizePanel = new JPanel(new FlowLayout());
        fontSizePanel.add(new Label("Font size:"));        
        this.txtFontSize = new JTextField(3);
        this.txtFontSize.setText(String.valueOf(Drawing.getFontSize()));
        this.txtFontSize.setEditable(false);
        fontSizePanel.add(txtFontSize);
        this.btnFontSizeLeft = new JButton("-");
        this.btnFontSizeLeft.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (Drawing.getFontSize() > 8) {
                    Drawing.setFontSize(Drawing.getFontSize() - 1);
                    Line.setFontSize(Drawing.getFontSize());
                    txtFontSize.setText(String.valueOf(Drawing.getFontSize()));
                    classDiagram.repaint();
                }
            }
        });
        fontSizePanel.add(this.btnFontSizeLeft);
        this.btnFontSizeRight = new JButton("+");
        this.btnFontSizeRight.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (Drawing.getFontSize() < 18) {
                    Drawing.setFontSize(Drawing.getFontSize() + 1);
                    Line.setFontSize(Drawing.getFontSize());
                    txtFontSize.setText(String.valueOf(Drawing.getFontSize()));
                    classDiagram.repaint();
                }
            }       
        });        
        fontSizePanel.add(this.btnFontSizeRight);
        frontPanel.add(fontSizePanel, BorderLayout.WEST);
        
        this.btnExport = new JButton("Export diagram");
        this.btnExport.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
                FileFilter pngFilter = new FileNameExtensionFilter("PNG (*.png)", "png");
                FileFilter jpegFilter = new FileNameExtensionFilter("JPEG (*.jpg)", "jpg");
                FileFilter bmpFilter = new FileNameExtensionFilter("BMP (*.bmp)", "bmp");
                JFileChooser fc = new JFileChooser();

                fc.addChoosableFileFilter(pngFilter);
                fc.addChoosableFileFilter(jpegFilter);
                fc.addChoosableFileFilter(bmpFilter);
                fc.setAcceptAllFileFilterUsed(false);
                
                int returnVal = fc.showSaveDialog(parentClass);
                
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    java.io.File savedFile = fc.getSelectedFile();
                    
                    String path = savedFile.getAbsolutePath();
                   
                    if (!(path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".bmp"))) {
                        if (fc.getFileFilter().equals(pngFilter)) {
                            path += ".png";
                        }
                        else if (fc.getFileFilter().equals(jpegFilter)) {
                            path += ".jpg";
                        }
                        else if (fc.getFileFilter().equals(bmpFilter)) {
                            path += ".bmp";
                        }
                    }
                    
                    java.io.File newFile = new java.io.File(path);
                    
                    BufferedImage bi = new BufferedImage(classDiagram.getWidth(), classDiagram.getHeight(), BufferedImage.TYPE_INT_ARGB); 
                    Graphics g = bi.createGraphics();
                    classDiagram.paint(g);  //this == JComponent
                    g.dispose();
                    try {               
                        ImageIO.write(bi, "png", newFile);
                    } catch (Exception ex) {
                        Message.showMessage("ClassDiagramView.java: " + ex.toString());
                    }
                }
            }
        });
        frontPanel.add(btnExport, BorderLayout.EAST);
        
        this.showAsociations = new JCheckBox("Show/Hide asociations");
        this.showAsociations.setSelected(true);
        this.showAsociations.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if(!showAsociations.isSelected()) {
                    showAtributes.setSelected(true);
                    showAtributes.setEnabled(false);
                    showAsociationNames.setEnabled(false);
                    showAsociationNames.setSelected(true);
                }
                else {
                    showAtributes.setEnabled(true);
                    showAtributes.setSelected(false);
                }
            }       
        });
        this.showAsociations.addItemListener(classDiagram);
        
        this.showAtributes = new JCheckBox("Show attributes");
        this.showAtributes.setSelected(false);
        this.showAtributes.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (showAtributes.isSelected()) {
                    showAsociationNames.setEnabled(true);
                }
                else {
                    showAsociationNames.setSelected(true);
                    showAsociationNames.setEnabled(false);
                }
                    
                Drawing.setShowAttributes(showAtributes.isSelected());
                classDiagram.repaint();
            }       
        });
        
        this.showAsociationNames = new JCheckBox("Show asociation names");
        this.showAsociationNames.setSelected(true);
        this.showAsociationNames.setEnabled(false);
        this.showAsociationNames.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                AsotiationArrow.setShowAsociationName(showAsociationNames.isSelected());
                classDiagram.repaint();
            }       
        });
        
        
        this.showConstructors = new JCheckBox("Show/Hide constructors");
        this.showConstructors.setSelected(false);
        this.showConstructors.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                Drawing.setShowConstructors(showConstructors.isSelected());
                classDiagram.repaint();
            }       
        });        
        
        JPanel menuPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        menuPanel.add(this.showAsociations);
        menuPanel.add(this.showAtributes);
        menuPanel.add(this.showAsociationNames);
        menuPanel.add(this.showConstructors);
        
        frontPanel.add(menuPanel, BorderLayout.CENTER); 
        ClassDiagramPanel.add(frontPanel, BorderLayout.NORTH);
        
        // pridanie canvasu
        JScrollPane scroll = new JScrollPane(classDiagram);
        ClassDiagramPanel.add(scroll, BorderLayout.CENTER);    
    }
    
    // komponenty package diagramu
    private void initComponentsPackage() {
        // rezia pre horny panel
        JPanel frontPanel = new JPanel(new BorderLayout());

        this.btnExport2 = new JButton("Export diagram");
        this.btnExport2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
                FileFilter pngFilter = new FileNameExtensionFilter("PNG (*.png)", "png");
                FileFilter jpegFilter = new FileNameExtensionFilter("JPEG (*.jpg)", "jpg");
                FileFilter bmpFilter = new FileNameExtensionFilter("BMP (*.bmp)", "bmp");
                JFileChooser fc = new JFileChooser();

                fc.addChoosableFileFilter(pngFilter);
                fc.addChoosableFileFilter(jpegFilter);
                fc.addChoosableFileFilter(bmpFilter);
                fc.setAcceptAllFileFilterUsed(false);
                
                int returnVal = fc.showSaveDialog(parentClass);
                
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    java.io.File savedFile = fc.getSelectedFile();
                    
                    String path = savedFile.getAbsolutePath();
                   
                    if (!(path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".bmp"))) {
                        if (fc.getFileFilter().equals(pngFilter)) {
                            path += ".png";
                        }
                        else if (fc.getFileFilter().equals(jpegFilter)) {
                            path += ".jpg";
                        }
                        else if (fc.getFileFilter().equals(bmpFilter)) {
                            path += ".bmp";
                        }
                    }
                    
                    java.io.File newFile = new java.io.File(path);
                    
                    BufferedImage bi = new BufferedImage(packageDiagram.getWidth(), packageDiagram.getHeight(), BufferedImage.TYPE_INT_ARGB); 
                    Graphics g = bi.createGraphics();
                    packageDiagram.paint(g);  //this == JComponent
                    g.dispose();
                    try {               
                        ImageIO.write(bi, "png", newFile);
                    } catch (Exception ex) {
                        Message.showMessage("ClassDiagramView.java: " + ex.toString());
                    }
                }
            }
        });
        frontPanel.add(btnExport2, BorderLayout.EAST);
        
        PackageDiagramPanel.add(frontPanel, BorderLayout.NORTH);
        
        // pridanie canvasu
        JScrollPane scroll = new JScrollPane(packageDiagram);
        PackageDiagramPanel.add(scroll, BorderLayout.CENTER);    
    }
}